﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Collections.Generic;
using System.Diagnostics;
using EffectLibrary;


namespace BouncingPlane
{
    public partial class Page : UserControl
    {

        long FirstClickTime;
        DataGrid dataGrid;

        public Page()
        {

            InitializeComponent();
        }


        private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs args)
        {

            if (((UIElement)args.OriginalSource) == null)
                return;

            //Get click position relative to the clicked object
            Point p = args.GetPosition((UIElement)args.OriginalSource);

            //Determine simple moment arm and direction against clicked object on both x & y axes.
            double DirectionalScalarY = (p.Y - (button1.RenderSize.Height / 2)) / (button1.RenderSize.Height / 2);
            double DirectionalScalarX = ((button1.RenderSize.Width / 2) - p.X) / (button1.RenderSize.Width / 2);


            //Apply only if on the top 10% of the clickable frame.
            if (DirectionalScalarY < -.90)
            {
                //Simulated double-click.  Each tick is .1 ms.
                //Setting double-click definition as two clicks
                //within 250 ms.
                if (DateTime.Now.Ticks - FirstClickTime < 10000 * 250)
                    FlipFrame(DirectionalScalarX);

                FirstClickTime = DateTime.Now.Ticks;
                return;
            }


            Storyboard sb = new Storyboard();
            //            button1.Projection = new PlaneProjection();

            DoubleAnimationUsingKeyFrames da = BuildKeyFrames(1.0, 80.0, 1.0, 35.0, DirectionalScalarX, 5.0);
            Storyboard.SetTarget(da, button1.Projection);
            Storyboard.SetTargetProperty(da, new PropertyPath("RotationY"));
            sb.Children.Add(da);

            da = BuildKeyFrames(1.0, 80.0, 1.0, 35.0, DirectionalScalarY, 5.0);
            Storyboard.SetTarget(da, button1.Projection);
            Storyboard.SetTargetProperty(da, new PropertyPath("RotationX"));
            sb.Children.Add(da);

            sb.Begin();

        }


        //My own hacked up physics model.
        DoubleAnimationUsingKeyFrames BuildKeyFrames(double Mass, double SpringConstant, double Dampening, double ForceMultiplier, double DirectionalScalar, double offset)
        {
            int sample = 75; //in ms
            int duration = 10000; //in ms

            //declare physics constants
            double lamda = Dampening / (2 * Math.Sqrt(SpringConstant * Mass));
            double omega_not = Math.Sqrt(SpringConstant / Mass);
            double omega_d = omega_not * Math.Sqrt(1.0 - Math.Pow(lamda, 2.0));
            double amplitude = DirectionalScalar * ForceMultiplier;

            DoubleAnimationUsingKeyFrames double_animation = new DoubleAnimationUsingKeyFrames();
            LinearDoubleKeyFrame frame;

            for (int i = 0; i < (duration / sample); i++)
            {
                frame = new LinearDoubleKeyFrame();
                frame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(i * sample));
                frame.Value = offset + amplitude * Math.Exp(-1 * lamda * omega_not * (double)sample * i / 1000) * Math.Sin(omega_d * i * sample / 1000);
                double_animation.KeyFrames.Add(frame);
            }

            return double_animation;
        }

        private void RadioButton_Effect(object sender, RoutedEventArgs e)
        {
            RadioButton rb = e.OriginalSource as RadioButton;

            if (rb == null)
                return;

            ClearEffects();

            switch (rb.Content as string)
            {

                case "Ripple":
                    PlaceHolder.Effect = new RippleEffect();
                    ((RippleEffect)PlaceHolder.Effect).Amplitude = 0.10;
                    ((RippleEffect)PlaceHolder.Effect).Frequency = 60;
                    GenerateRipples((RippleEffect)PlaceHolder.Effect);
                    break;

                case "Magnify":
                    PlaceHolder.Effect = new SmoothMagnifyEffect();
                    ((SmoothMagnifyEffect)PlaceHolder.Effect).InnerRadius = 0.150;
                    ((SmoothMagnifyEffect)PlaceHolder.Effect).OuterRadius = 0.20;
                    break;

                case "ColorKeyAlpha":
                    PlaceHolder.Effect = new ColorKeyAlphaEffect();


                    string sR = "0";
                    string sG = ((int)(255.0 * 0.819)).ToString();
                    string sB = ((int)(255.0 * 0.921)).ToString();

                    Color c = Color.FromArgb(
                        byte.Parse("0"),
                        byte.Parse(sR),
                        byte.Parse(sG),
                        byte.Parse(sB));

                    ((ColorKeyAlphaEffect)PlaceHolder.Effect).ColorKey = c;

                    break;

                default:
                    return;
            }

        }

        //Helper method to clear all effects.
        void ClearEffects()
        {

            if (ChildHolder != null)
                ChildHolder.Effect = null;

            if (PlaceHolder != null)
                PlaceHolder.Effect = null;

        }

        private void GenerateRipples(RippleEffect ripple)
        {
            Storyboard sb = new Storyboard();
            DoubleAnimation da = new DoubleAnimation();

            da.By = -1.0 * Math.PI * 2.0;
            da.FillBehavior = FillBehavior.HoldEnd;
            da.Duration = new Duration(TimeSpan.FromMilliseconds(1000));
            da.RepeatBehavior = RepeatBehavior.Forever;

            sb.Children.Add(da);

            Storyboard.SetTarget(da, ripple);
            Storyboard.SetTargetProperty(da, new PropertyPath("Phase"));
            sb.Begin();
        }

        //Create simple plane hover.
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            FirstClickTime = DateTime.Now.Ticks;
            Storyboard sb = new Storyboard();
            DoubleAnimation da = new DoubleAnimation();
            da.From = -3.0;
            da.To = 3.0;
            da.Duration = new Duration(TimeSpan.FromMilliseconds(1000));
            da.AutoReverse = true;
            da.RepeatBehavior = RepeatBehavior.Forever;

            button1.RenderTransform = new TranslateTransform();
            Storyboard.SetTarget(da, button1.RenderTransform);
            Storyboard.SetTargetProperty(da, new PropertyPath("Y"));
            sb.Children.Add(da);
            sb.Begin();
        }

        //For some of the effects, apply to where the mouse is.
        private void Border_MouseMove(object sender, MouseEventArgs args)
        {

            if (PlaceHolder == null)
                return;

            if (PlaceHolder.Effect == null)
                return;

            Point p = new Point();
            p.X = args.GetPosition(button1).X / (button1.RenderSize.Width);
            p.Y = args.GetPosition(button1).Y / (button1.RenderSize.Height);

            if (PlaceHolder.Effect.GetType().Equals(typeof(RippleEffect)))
                ((RippleEffect)PlaceHolder.Effect).Center = p;

            if (PlaceHolder.Effect.GetType().Equals(typeof(SmoothMagnifyEffect)))
                ((SmoothMagnifyEffect)PlaceHolder.Effect).Center = p;

        }

        private void RadioButton_Control(object sender, RoutedEventArgs e)
        {

            RadioButton rb = sender as RadioButton;
            if (rb == null || button1 == null)
                return;


            switch (rb.Content.ToString())
            {
                case "None":
                    ChildHolder.Child = null;
                    break;

                case "HD Video":

                    //I didn't include the video used in the demo since it's relatively
                    //relatively large but just include the video in your project
                    //and fill in the correct path.


                    //MediaElement me = new MediaElement();
                    //me.MediaEnded += new RoutedEventHandler(me_MediaEnded);
                    //me.Stretch = Stretch.Fill;
                    //me.Source = new Uri("wildlife.wmv", UriKind.RelativeOrAbsolute);
                    //ChildHolder.Child = me;

                    break;

                case "DataGrid":
                    //   ChildHolder.Child = (UIElement)GetSampleDataGrid();
                    break;

                default:
                    break;
            }


        }

        //Loop video
        void me_MediaEnded(object sender, RoutedEventArgs e)
        {
            if (e.OriginalSource == null)
                return;

            ((MediaElement)e.OriginalSource).Stop();
            ((MediaElement)e.OriginalSource).Play();

        }


        private void RadioButton_Checked(object sender, RoutedEventArgs e)
        {

            RadioButton rb = sender as RadioButton;
            if (rb == null || button1 == null)
                return;

            switch (rb.Content.ToString().ToLower())
            {

                case "none":
                    PlaceHolder.Background = new SolidColorBrush(Colors.Transparent);
                    break;
                default:
                    ImageBrush ib = new ImageBrush();
                    BitmapImage bmi;
                    ib = new ImageBrush();
                    bmi = new BitmapImage(new Uri("images/" + rb.Content.ToString() + ".jpg", UriKind.RelativeOrAbsolute));
                    ib.ImageSource = bmi;
                    ib.Stretch = Stretch.UniformToFill;
                    PlaceHolder.Background = ib;
                    return;
            }


        }

        //Simple function for flipping the content frame on the
        //horizontal axis.  Because this is replacing the animation
        //for the bounce, need to recreate side to side bounce.

        public void FlipFrame(double DirectionalScalarX)
        {
            Storyboard sb = new Storyboard();
            DoubleAnimation da1 = new DoubleAnimation();
            da1.From = -5.0;
            da1.To = -355.0;
            da1.Duration = new Duration(TimeSpan.FromMilliseconds(550.0));
            SineEase se = new SineEase();
            se.EasingMode = EasingMode.EaseInOut;
            da1.EasingFunction = se;

            Storyboard.SetTarget(da1, button1.Projection);
            Storyboard.SetTargetProperty(da1, new PropertyPath("RotationX"));

            DoubleAnimationUsingKeyFrames da2 = BuildKeyFrames(1.0, 80.0, 1.0, 35.0, DirectionalScalarX, 5.0);
            Storyboard.SetTarget(da2, button1.Projection);
            Storyboard.SetTargetProperty(da2, new PropertyPath("RotationY"));

            sb.Children.Add(da1);
            sb.Children.Add(da2);
            sb.Begin();

        }

      

     

        private void Image_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            // TODO: Add event handler implementation here.
            Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;
        }

        private void SoundOnOff(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            // TODO: Add event handler implementation here.
            if (mediaIndicator.Visibility == Visibility.Collapsed)
            {
                mediaBgSound.Stop();
                mediaIndicator.Visibility = Visibility.Visible;
            }
            else
            {
                mediaIndicator.Visibility = Visibility.Collapsed;
                mediaBgSound.Play();

            }



        }

        private void SocialButton_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
        	// TODO: Add event handler implementation here.
            SocialButtonMouseOverStoryboard.Begin();
        }

    }


}
